package com.rtech.app.service;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.rtech.app.constant.TraversalConstant;
import com.rtech.app.exception.SearchException;

/**
 * Implementation class for file server search service.
 * 
 * @author ruchi.singhal
 * 
 */
@Service
public class TraversalServiceImpl implements TraversalService {

	protected static Logger logger = Logger.getLogger("TraversalServiceImpl");

	/**
	 * Method used to fetch the information about the input file like file name,
	 * file location and permission attached with file etc.
	 * 
	 * @param filePath
	 *            - path of the file on the server for lookup
	 * @return file object with desired information to user
	 */
	public com.rtech.app.model.File fileSearch(String filePath)
			throws SearchException {
		logger.debug("Entering into fileSearch() >>> ");
		com.rtech.app.model.File fileDetail = new com.rtech.app.model.File();
		try {
			java.io.File f = new java.io.File(filePath);
			String permission = "";
			if (f.exists()) {
				fileDetail.setExist(true);
				permission += f.canRead() ? TraversalConstant.PERMISSION_READ
						+ "," : "";
				permission += f.canWrite() ? TraversalConstant.PERMISSION_WRITE
						+ "," : "";
				permission += f.canExecute() ? TraversalConstant.PERMISSION_EXECUTE
						+ ","
						: "";

				permission = permission.substring(0, permission.length() - 1);
				logger.debug("permission - " + permission);
				fileDetail.setPermissions(permission);

			} else {
				logger.debug("requeste file not exist on server");
				fileDetail.setExist(false);
			}
		} catch (Exception e) {
			logger.error(" ERROR: in directorySearch ");
			throw new SearchException("ERROR " + e.getMessage());
		}

		logger.debug("Exiting from into fileSearch() >>> ");
		return fileDetail;
	}

	/**
	 * Method used to fetch the complete information about the input directory.
	 * 
	 * @param dirPath
	 *            - path of directory for which user need information
	 * @return directory information
	 */
	public com.rtech.app.model.Directory directorySearch(String dirPath)
			throws SearchException {

		logger.debug(" dirPath : " + dirPath);
		com.rtech.app.model.Directory dirs = new com.rtech.app.model.Directory();
		try {

			dirs.setDirName(dirPath);
			java.io.File fl = new java.io.File(dirPath);
			if (fl.exists()) {
				dirs.setDirName(dirPath);
				traverse(dirs, "");
			} else {
				dirs.setDirName(dirPath);
			}
		} catch (Exception e) {
			logger.error(" ERROR: in directorySearch ");
			throw new SearchException("ERROR " + e.getMessage());
		}
		logger.debug(" Exiting from directorySearch() >>> ");
		return dirs;
	}

	/**
	 * Method used to traverse the directory for search result.
	 * 
	 * @param dirs
	 *            - object of Directory
	 * @param name
	 *            - name of child
	 */
	private void traverse(com.rtech.app.model.Directory dirs, String name) {

		logger.debug(" ******************************** ");
		logger.debug(" Entering into traverse() >>> ");

		String dirPath = dirs.getDirName();
		if (!"".equals(name)) {
			dirPath = dirPath + "/" + name;
		}
		logger.debug("Diretory Name " + dirPath);
		java.io.File file = new java.io.File(dirPath);

		if (file.isDirectory()) {
			com.rtech.app.model.Directory newDir = new com.rtech.app.model.Directory();
			newDir.setDirName(dirPath);
			dirs.getDirs().add(newDir);
			String entries[] = file.list();
			if (entries != null) {
				for (String entry : entries) {
					logger.debug(" entry " + entry);
					newDir = new com.rtech.app.model.Directory();
					newDir.setDirName(dirPath);
					dirs.getDirs().add(newDir);
					logger.debug("calling traverse " + newDir.getDirName());
					traverse(newDir, entry);
				}
			}
		} else {
			com.rtech.app.model.File fileDetail = new com.rtech.app.model.File();
			fileDetail.setName(file.getName());
			if (file.exists()) {
				fileDetail.setExist(true);
			} else {
				logger.debug("requeste file not exist on server");
				fileDetail.setExist(false);
			}
			dirs.getFiles().add(fileDetail);
		}
	}

}
